<template>
  <Teleport to="body">
    <Transition name="vt-modal-fade">
      <div
        v-if="visible"
        class="vt-modal-mask"
        :style="{ zIndex }"
        @click="handleMaskClick"
      >
        <div
          class="vt-modal-wrapper"
          :class="{ 'vt-modal-wrapper--centered': centered }"
        >
          <Transition name="vt-modal-zoom">
            <div
              v-if="visible"
              class="vt-modal"
              :style="modalStyle"
              @click.stop
            >
              <!-- Header -->
              <div v-if="title || closable" class="vt-modal__header">
                <div class="vt-modal__title">
                  <slot name="title">{{ title }}</slot>
                </div>
                <button
                  v-if="closable"
                  class="vt-modal__close"
                  @click="handleClose"
                >
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                    <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
                  </svg>
                </button>
              </div>

              <!-- Body -->
              <div class="vt-modal__body">
                <slot></slot>
              </div>

              <!-- Footer -->
              <div v-if="showFooter" class="vt-modal__footer">
                <slot name="footer">
                  <button class="vt-modal__btn vt-modal__btn--cancel" @click="handleCancel">
                    {{ cancelText }}
                  </button>
                  <button 
                    class="vt-modal__btn vt-modal__btn--ok"
                    :class="{ 'vt-modal__btn--loading': okLoading }"
                    :disabled="okLoading"
                    @click="handleOk"
                  >
                    <span v-if="okLoading" class="vt-modal__loading">
                      <svg class="vt-modal__loading-icon" viewBox="0 0 24 24">
                        <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" opacity="0.25"/>
                        <path d="M12 2 A 10 10 0 0 1 22 12" stroke="currentColor" stroke-width="2" fill="none">
                          <animateTransform
                            attributeName="transform"
                            type="rotate"
                            values="0 12 12;360 12 12"
                            dur="1s"
                            repeatCount="indefinite"
                          />
                        </path>
                      </svg>
                    </span>
                    {{ okText }}
                  </button>
                </slot>
              </div>
            </div>
          </Transition>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<script setup lang="ts">
import { computed, watch, nextTick } from 'vue'
import type { ModalProps, ModalEmits } from './types'

const props = withDefaults(defineProps<ModalProps>(), {
  visible: false,
  title: '',
  width: 520,
  closable: true,
  maskClosable: true,
  destroyOnClose: false,
  centered: false,
  zIndex: 1000,
  showFooter: true,
  okText: '确定',
  cancelText: '取消',
  okLoading: false
})

const emit = defineEmits<ModalEmits>()

const modalStyle = computed(() => {
  const width = typeof props.width === 'number' ? `${props.width}px` : props.width
  return {
    width,
    maxWidth: '90vw'
  }
})

const handleMaskClick = () => {
  if (props.maskClosable) {
    handleClose()
  }
}

const handleClose = () => {
  emit('update:visible', false)
  emit('close')
}

const handleOk = () => {
  emit('ok')
}

const handleCancel = () => {
  emit('cancel')
  handleClose()
}

// 监听visible变化，处理body滚动
watch(() => props.visible, (visible) => {
  nextTick(() => {
    if (visible) {
      document.body.style.overflow = 'hidden'
    } else {
      document.body.style.overflow = ''
    }
  })
})
</script>

<style scoped>
.vt-modal-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 50px 20px;
  overflow-y: auto;
}

.vt-modal-wrapper {
  width: 100%;
  display: flex;
  justify-content: center;
}

.vt-modal-wrapper--centered {
  align-items: center;
  min-height: 100%;
}

.vt-modal {
  background: #ffffff;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  position: relative;
  margin: 0 auto;
}

.vt-modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px 16px;
  border-bottom: 1px solid #f0f0f0;
}

.vt-modal__title {
  font-size: 16px;
  font-weight: 600;
  color: #262626;
  line-height: 1.5;
}

.vt-modal__close {
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  color: #8c8c8c;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.vt-modal__close:hover {
  background-color: #f5f5f5;
  color: #595959;
}

.vt-modal__body {
  padding: 24px;
  min-height: 80px;
  color: #262626;
  line-height: 1.6;
}

.vt-modal__footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  padding: 16px 24px 20px;
  border-top: 1px solid #f0f0f0;
}

.vt-modal__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 16px;
  border-radius: 4px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
  border: 1px solid transparent;
  min-width: 80px;
  height: 36px;
}

.vt-modal__btn--cancel {
  background: #ffffff;
  border-color: #d9d9d9;
  color: #595959;
}

.vt-modal__btn--cancel:hover {
  border-color: #40a9ff;
  color: #40a9ff;
}

.vt-modal__btn--ok {
  background: #1677ff;
  border-color: #1677ff;
  color: #ffffff;
}

.vt-modal__btn--ok:hover:not(.vt-modal__btn--loading) {
  background: #4096ff;
  border-color: #4096ff;
}

.vt-modal__btn--loading {
  cursor: not-allowed;
  opacity: 0.7;
}

.vt-modal__loading {
  display: inline-flex;
  align-items: center;
  margin-right: 6px;
}

.vt-modal__loading-icon {
  width: 14px;
  height: 14px;
}

/* 动画效果 */
.vt-modal-fade-enter-active,
.vt-modal-fade-leave-active {
  transition: opacity 0.3s ease;
}

.vt-modal-fade-enter-from,
.vt-modal-fade-leave-to {
  opacity: 0;
}

.vt-modal-zoom-enter-active,
.vt-modal-zoom-leave-active {
  transition: all 0.3s ease;
}

.vt-modal-zoom-enter-from,
.vt-modal-zoom-leave-to {
  opacity: 0;
  transform: scale(0.7);
}
</style>